K.

requires("K.lang.Function").

includes("K.lang.Reflect").

provides("K.dom.Element").
run(function(I) {
    
    var Element = K.kin(function(o, element) {
        K.merge(o, {
            attr : I.Function.overload(
                function(a) {
                    if (I.Reflect.isObject(a)) {
                        K.forEach(a, function(v, p) {
                            o.attr(p, v);
                        });
                    } else {
                        return element.getAttribute(a);
                    }
                },
                function(a, v) {
                    element.setAttribute(a, v);
                }),
            
            raw : function() {
                return element;
            },
            
            addClass : function(c) {
                if (!o.hasClass(c)) {
                    o.attr("class", o.classes().concat([c]).join (" "));
                }
            },
            
            hasClass : function(c) {
                return o.classes().some(function(e) {
                    return e === c;
                });
            },
            
            removeClass : function(c) {
                if (o.hasClass(c)) {
                    o.attr("class", o.classes().filter(function(v) { return c !== v; }).join(" ")); 
                }
            },
            
            classes : function() {
                var c = o.attr("class");
                return c ? c.split(/\s+/) : [];
            },
            
            html : function(html) {
                element.innerHTML = html;
            },
            
            append : function(v) {
                if (v instanceof Element) {
                    v = v.raw();
                }
                
                element.appendChild(v);
            },
            
            style : I.Function.overload(
                function(p) {
                    if (I.Reflect.isObject(p)) {
                        K.forEach(p, function(v, p) {
                            o.style(p, v);
                        });
                    } else {
                        return element.style[p];
                    }
                },            
                function(p, v) {
                    element.style[p] = v;
                }),
                
            find : function(selector) {
                return Element(element.querySelector(selector));
            }
            
        });
    });
    
    return Element;
    
});